#include <iostream>
#include <fstream>
#include "contacts.pb.h" //默认先从当前目录；然后没有再去系统对应目录
#include <string>

using namespace std;

void add_contacters(contacts::PersonInfo *persons)
{

    cout << "-------------新增联系⼈-------------" << endl;
    cout << "请输入联系人姓名：";
    string name;
    getline(cin, name); // 遇到缓冲区的\n默认停止并删除它
    persons->set_name(name);
    cout << "请输入联系人年龄：";
    int age;
    cin >> age; // 缓冲区留着\n需要手动清除
    persons->set_age(age);
    cin.ignore(256, '\n'); // 最大值值读取256个读到就删除完终止；没有读完256个直接终止

    // 输入所有的电话号码：

    for (int i = 0;; i++)
    {

        cout << "请输入联系人电话" << i + 1 << "(只输⼊回⻋完成电话新增):";

        string number;

        getline(cin, number);

        // 进行是否停止的判断：

        if (number.empty())
        {
            break;
        }

        contacts::PersonInfo_Phone *phone = persons->add_phone();
        phone->set_number(number);
        cout << "请输入该电话类型(1、移动电话   2、固定电话): ";
        int type;
        cin >> type;
        cin.ignore(256, '\n');
        switch (type)
        {

        case 1:
            phone->set_type(contacts::PersonInfo_Phone_PhoneType::PersonInfo_Phone_PhoneType_MF);
            break;
        case 2:
            phone->set_type(contacts::PersonInfo_Phone_PhoneType::PersonInfo_Phone_PhoneType_TEL);
            break;
        default:
            cout << "选择有误！" << endl;
            break;
        }
    }
    contacts::Address address;

    cout << "请输入联系人家庭地址：";

    string home;

    getline(cin, home);

    address.set_home_address(home);
    cout << "请输入联系人工作地址：";
    string work;
    getline(cin, work);
    address.set_work_address(work);

    // 进行加入Any管理的变量（把对应地址）：
    persons->mutable_data()->PackFrom(address);

    // oneof测试：qq与wechat

    cout << "请选择要添加的其他联系方式(1、qq     2、微信号):";

    int contact;
    cin >> contact;
    cin.ignore(256, '\n');
    if (contact == 1)
    {
        cout << "请输入联系人qq号: ";
        string qq;
        getline(cin, qq);
        persons->set_qq(qq);
    }

    else if (contact == 2)
    {

        cout << "请输入联系人微信号: ";
        string wechat;
        getline(cin, wechat);
        persons->set_qq(wechat);
    }
    else
    {
        cout << "选择有误，未成功设置其他联系方式！" << endl;
    }

    for (int i = 0;; i++)
    {

        cout << "请输入备注" << i + 1 << "标题(只输入回车完成备注新增):";

        string key;
        getline(cin, key);
        if (key.empty())  {break;}
        cout << "请输入备注" << i + 1 << "内容: ";
        string value;
        getline(cin, value);
        persons->mutable_comment()->insert({key,value});
    }
}

int main()
{

    contacts::Contacts contacts;

    // 读取对应二进制protobuf格式存储的文件+输入文件

    // 读取对应文件:
    std::fstream input("contacts.bin", std::ios::in | std::ios::binary); // 不存在文件自动创建

    if (!input)
    { // 不存在自动创建后对应文件指针就是nullptr

        std::cout << "contacts.bin not find, create new file!" << std::endl;
    }

    // 如果对应文件存在也就是里面有内容（此时就需要加入对应对象中然后再进行添加；最后一再次从头写入：

    else if (!contacts.ParseFromIstream(&input))
    {
        cerr << "parse error!" << endl;
        input.close();
        return -1;
    }

    // 进行添加对应联系人：

    // 1.完成对应的PersonInfo数组填充：
    add_contacters(contacts.add_contacts()); // 对于类套类时候；必须这样添加对应没有对应set_object等操作(从对应对象成员后面的位置开始添加；也就是返回下一个的地址)

    // 2.写入文件：

    std::fstream output("contacts.bin", std::ios::out | std::ios::binary);

    if (!contacts.SerializeToOstream(&output))
    {
        cerr << "write error!" << endl;
        input.close();
        output.close();
        return -1;
    }

    cout << "write success!" << endl;
    input.close();
    output.close();
    return 0;
}